ResMgr = {};

local abDic = nil;
local abFilePathDic = nil;
ResMgr.CMain = nil;

function ResMgr:init()
    ResMgr.CMain = GameObject.Find("Main"):GetComponent("Main");
    if not Main.isUseEditorRes then
        ResMgr:loadAllAB();
    end
end

local preloadCount = nil;
local preloadMaxCount = nil;
function ResMgr:preloadPrefab()
    if Main.isUseEditorRes then
        Dispatcher:dispatch(EventType.PreloadProgress, 1);
        return;
    end
    local cfg = ConfigMgr:load("Preload");
    preloadCount = 0;
    preloadMaxCount = #cfg;
    if #cfg == 0 then
        Dispatcher:dispatch(EventType.PreloadProgress, 1);
        return;
    end
    for i, v in ipairs(cfg) do
        local ab = ResMgr:getAB(v);
        ResMgr.CMain:LoadAssetAsync(ab, Utils.pathGetFileName(v), function()
            preloadCount = preloadCount + 1;
            Dispatcher:dispatch(EventType.PreloadProgress, preloadCount / preloadMaxCount);
        end, false);
    end
end

function ResMgr:loadAllAB()
    abDic = {};
    abFilePathDic = {};
    local filesPath = Application.persistentDataPath .. "/files.txt";
    if not Utils.fileExists(filesPath) then
        filesPath = Application.streamingAssetsPath .. "/files.txt";
    end
    --Application.streamingAssetsPath下面的文件可能在安卓下用ReadAllLines读取不了，需要换成www读取
    local files = Utils.readAllLines(filesPath);
    for i = 0, files.Length - 1 do
        local abPath = Utils.split(files[i], "|")[0];
        if Utils.pathGetExtension(abPath) == ".ab" then
            local abFilePath = Application.persistentDataPath .. abPath;
            if not Utils.fileExists(abFilePath) then
                abFilePath = Application.streamingAssetsPath .. abPath;
            end
            local ab = AssetBundle.LoadFromFile(abFilePath);
            local splitArr = Utils.split(abPath, "/");
            local prefabPath = Utils.replace(splitArr[splitArr.Length - 1], ".ab", "");
            prefabPath = Utils.replace(prefabPath, "_", "/");
            abDic[prefabPath] = ab;
            abFilePathDic[prefabPath] = abFilePath;
        end
    end
end

function ResMgr:unLoadAllAB()
    for k, v in pairs(abDic) do
        ResMgr.CMain:RemoveAssetObject(v);
        v:Unload(true);
        abDic[k] = nil;
    end
end

function ResMgr:getAB(prefabPath)
    prefabPath = Utils.toLower(prefabPath);
    local ab = abDic[prefabPath];
    if not ab then
        ab = abDic[Utils.split(prefabPath, "/")[0]];
    end
    if not ab and abFilePathDic[prefabPath] then
        ab = AssetBundle.LoadFromFile(abFilePathDic[prefabPath]);
        abDic[prefabPath] = ab;
    end
    return ab;
end

function ResMgr:clearRes(prefabPath)
    if Main.isUseEditorRes or prefabPath == nil then
        return;
    end
    prefabPath = Utils.toLower(prefabPath);
    local ab = abDic[prefabPath];
    if not ab then
        prefabPath = Utils.split(prefabPath, "/")[0];
        ab = abDic[prefabPath];
    end
    if ab then
        ResMgr.CMain:RemoveAssetObject(ab);
        Utils.log("ClearRes", ab);
        ab:Unload(true);
        abDic[prefabPath] = nil;
    end
end

function ResMgr:loadPrefab(prefabPath, complete)
    local gameObject = nil;
    if prefabPath == nil then
        gameObject = GameObject();
        complete(gameObject);
    else
        if Main.isUseEditorRes then
            local obj = AssetDatabase.LoadAssetAtPath("Assets/ExternalRes/Prefab/" .. prefabPath .. ".prefab", typeof(GameObject));
            gameObject = GameObject.Instantiate(obj);
            --complete(gameObject);--同步
            TimeMgr:delayFrame(1, complete, gameObject);--异步
        else
            -- load prefab to AssetBundle
            -- 以下是同步加载
            -- local ab = ResMgr:getAB(prefabPath);
            -- local obj = ab:LoadAsset(Utils.pathGetFileName(prefabPath));
            -- gameObject = GameObject.Instantiate(obj);
            -- complete(gameObject);
            -- 以下是异步加载
            local ab = ResMgr:getAB(prefabPath);
            ResMgr.CMain:LoadAssetAsync(ab, Utils.pathGetFileName(prefabPath), complete);
        end
    end
end

--获取图集里面的精灵是同步操作
function ResMgr:getAtlasprite(prefabPath, spriteName)
    if Main.isUseEditorRes then
        local atlas = AssetDatabase.LoadAssetAtPath("Assets/ExternalRes/Prefab/" .. prefabPath .. ".spriteatlas", typeof(SpriteAtlas));
        return atlas:GetSprite(spriteName);
    else
        local ab = ResMgr:getAB(prefabPath);
        return ResMgr.CMain:GetAssetObject(ab, Utils.pathGetFileName(prefabPath)):GetSprite(spriteName);
    end
end

function ResMgr:getSound(soundName, complete)
    local sound = nil;
    if Main.isUseEditorRes then
        sound = AssetDatabase.LoadAssetAtPath("Assets/ExternalRes/Prefab/Sound/" .. soundName .. ".wav", typeof(AudioClip));
        if not sound then
            sound = AssetDatabase.LoadAssetAtPath("Assets/ExternalRes/Prefab/Sound/" .. soundName .. ".mp3", typeof(AudioClip));
        end
        TimeMgr:delayFrame(1, complete, sound);--异步
    else
        local ab = ResMgr:getAB("Sound/" .. soundName);
        -- 以下是同步加载
        -- sound = ab:LoadAsset(SoundName);
        -- 以下是异步加载
        ResMgr.CMain:LoadAssetAsync(ab, soundName, complete, false);
    end
end